def header(package_name: str, classname: str) -> str:
    ret = f"package {package_name}\r\n\r\n"
    ret += '''import org.squirrelframework.foundation.fsm.annotation.*
import org.squirrelframework.foundation.fsm.impl.AbstractUntypedStateMachine\r\n'''
    
    return ret


def states_header() -> str:
    return '@States(\r\n'


def states_repr(machine, classname, parent_state=None) -> str:
    ret = ""

    for state in machine.states:
        if parent_state is None:
            ret += (' ' * 8 + f'State(name = {classname}.S_{state.name}),\r\n')
        else:
            ret += (' ' * 8 + f'State(name = {classname}.S_{state.name}, parent = {classname}.S_{parent_state}),\r\n')

        if state.sub_machine:
            ret += states_repr(state.sub_machine, classname, state.name)

    return ret[:-3] + '\r\n'


def states_footer() -> str:
    return ")\r\n"


def transitions_header() -> str:
    return "@Transitions(\r\n"


def transitions_repr(machine, classname) -> str:
    ret = ""

    for t in machine.transitions:
        ret += (' ' * 8 + f'Transit(from = {classname}.S_{t.from_state}, to = {classname}.S_{t.to_state}, on = {classname}.E_{t.trigger}, callMethod = "{t.transition_method_name()}"),\r\n')

    for s in machine.states:
        if not (s.sub_machine is None):
            ret += transitions_repr(s.sub_machine, classname)

    return ret[:-3] + '\r\n'


def transitions_footer() -> str:
    return ")\r\n"


def context_annotation() -> str:
    return "@StateMachineParameters(stateType = String::class, eventType = String::class, contextType = Any::class)\r\n"


def class_declaration_start(classname: str) -> str:
    return f'class {classname}: AbstractUntypedStateMachine() {{\r\n\r\n'


def companion_declaration_start() -> str:
    return '    companion object {\r\n'


def states_declaration(state_names) -> str:
    ret = ''
    for state in state_names:
        ret += f'        const val S_{state} = "{state}"\r\n'

    return ret


def events_declaration(event_names) -> str:
    ret = ''
    for trigger in event_names:
        ret += f'        const val E_{trigger} = "{trigger}";\r\n'

    return ret


def companion_declaration_end() -> str:
    return '    }\r\n'


def transition_methods_repr(methods) -> str:
    ret = ''
    for method in methods:
        ret += f'    private fun {method}(from: String, to: String, event: String, context: Any) {{}}\r\n\r\n'

    return ret


def class_declaration_end():
    return '}\r\n'

